package communication.server.vertx.service.impl;

import communication.common.business.base.FcrSocketAddress;
import communication.common.vertx.net.ProtocolEnum;
import communication.server.vertx.dao.DeviceInfoDao;
import communication.server.vertx.entity.DeviceInfo;
import communication.common.vertx.net.NetManager;
import communication.common.business.base.MsgData;
import communication.common.business.hole.P2pHoleRequest;
import communication.common.business.device.DeviceService;
import communication.common.business.util.NetSocketUtil;
import io.vertx.core.datagram.DatagramSocket;
import io.vertx.core.net.NetSocket;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.stereotype.Component;

/**
 * @author mac
 */
@Component
@Data
@AllArgsConstructor
public class DeviceServiceImpl implements DeviceService {


    private final DeviceInfoDao deviceInfoDao;

    private final NetManager netManager;

    /**
     *  转发打动请求到指定的目标socket
     * @param request
     */
    @Override
    public void transferHoleRequest(P2pHoleRequest request, ProtocolEnum protocolEnum) throws Exception {
        DeviceInfo deviceInfo = deviceInfoDao.getByUserId(request.getTargetUserId());

        MsgData data= MsgData.builder()
                .module("device")
                .op("hole")
                .opParam(new Object[]{request})
                .build();

        // 判断socekt使用的协议
        switch (protocolEnum){
            case TCP:
                 transferHoleRequestOnTcp(deviceInfo, data);
                 break;
            case UDP:
                 transferHoleRequestOnUdp(deviceInfo, data);
            default:
                throw new RuntimeException("暂不支持的协议:"+protocolEnum);
        }


    }

    private void transferHoleRequestOnTcp(DeviceInfo deviceInfo, MsgData data) throws Exception {
        FcrSocketAddress remoteSocketAddress = FcrSocketAddress.getByString(deviceInfo.getNetAddress());
        NetSocket target = netManager.getTcpSocketByKey( remoteSocketAddress);

        if(target == null){
            throw new Exception("target tcp socket not non-existent");
        }

        NetSocketUtil.sendObj(target, data);

    }

    private void transferHoleRequestOnUdp(DeviceInfo deviceInfo, MsgData data) throws Exception {

        FcrSocketAddress remoteSocketAddress = FcrSocketAddress.getByString(deviceInfo.getNetAddress());
        // 核心功能，转发打洞请求到目标主机
        DatagramSocket target = netManager.getUdpSocketByKey(remoteSocketAddress  );

        if(target == null){
            throw new Exception("target udp socket not non-existent");
        }

        NetSocketUtil.sendObj(target, remoteSocketAddress.getHost(), remoteSocketAddress.getPort(), data);
    }


    /**
     * todo:
     * @param request 打洞请求
     * @throws Exception
     */
    @Override
    public void doHole(P2pHoleRequest request) throws Exception {

    }
}
